package com.bwie.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.domain.Brand;
import com.bwie.es.EsBrandVo;
import com.bwie.mapper.BrandMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: E-Commerce-Month-01
 * @BelongsPackage: com.bwie.task
 * @Author: asus
 * @CreateTime: 2025-11-01  08:34
 * @Description: 同步品牌数据 || 同步增量数据
 * @Version: 1.0
 */
@Component
public class EsBrandTask {
    /* [Es Brand同步任务] */
    @Autowired private ElasticsearchRestTemplate elasticsearchRestTemplate; // Es 操作
    @Autowired private StringRedisTemplate redisTemplate ;// Redis 操作
    @Autowired private BrandMapper brandMapper; // mapper

    /* 定义缓存时间 */
    public static  final String BRAND_TIME_KEY = "Brand-Data-To-Es";
    @Scheduled(cron = "0 * * * * ?")
    public void BrandDataToEs(){
        System.out.println("[Es Brand同步任务] 开始同步Es任务，时间："+ DateUtil.now());

        /* 1、判断是否存在 es_brand 索引，不存在创建索引 && 创建映射  */
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(EsBrandVo.class);
        if (!indexOperations.exists()){
            // 索引不存在 创建索引
            indexOperations.create();
            // 创建映射 mapping
            Document mapping = indexOperations.createMapping();
            indexOperations.putMapping(mapping);
            System.out.println("[Es Brand同步任务] es_brand 索引已创建，mapping 映射已创建");
        }
        // 创建大分页 1-99999
        Page<Brand> brandPage = new Page<>(1, 99999);
        // 定义返回时间
        String now = DateUtil.now();

        /* 2、判断 redis Key ， 首次同步 true 全量同步，false 增量同步 */
        if (!redisTemplate.hasKey(BRAND_TIME_KEY)){
            //全量数据查询
            Page<Brand> page = brandMapper.selectListByPage(brandPage,null,null);
            System.out.println("[Es Brand同步任务] 全量数据同步， 查询"+page.getRecords().size()+"条数据");
            this.syncBrandDataToEs(page.getRecords());
        }else {
            String redisBrand = redisTemplate.opsForValue().get(BRAND_TIME_KEY);
            Page<Brand> page = brandMapper.selectListByPage(brandPage,null,redisBrand);
            System.out.println("[Es Brand同步任务] 增量数据同步，查询"+page.getRecords().size()+"条数据");
            this.syncBrandDataToEs(page.getRecords());
        }
        /* 4、返回 时间 30分钟，防止数据勾留*/
        redisTemplate.opsForValue().set(BRAND_TIME_KEY,now,30, TimeUnit.MINUTES);
        System.out.println("[Es Brand同步任务] 数据同步Es完成，时间："+DateUtil.now());
    }
    /* 3、循环数据传递，brandList -> EsBrandVo 循环同步*/
    private void  syncBrandDataToEs(List<Brand> brandList){
        //空保护
        if(brandList == null || brandList.isEmpty()){
            System.out.println("[Es Brand同步任务] 数据列表为空，跳过");
            return;
        }
        //循环同步数据
        for (Brand brand : brandList) {
            EsBrandVo esBrandVo = new EsBrandVo();
            BeanUtil.copyProperties(brand,esBrandVo);
            elasticsearchRestTemplate.save(esBrandVo);
        }
        System.out.println("[Es Brand同步任务] 同步数据成功"+brandList.size()+"条数据");
    }
}
